import os
from functools import wraps
from os.path import dirname, split as split_path, splitext

import bpy
from bpy.props import StringProperty
from mathutils import Vector, Matrix

from ..utils.log import log
from ..utils.preferences import Preferences


def import_handle(func):
    """
    处理进入或退出模态或方法
    添加更改或删除数据
    """

    @wraps(func)
    def decorated(*args, **kwargs):
        self = args[0]
        self.before_handle()
        ret = func(*args, **kwargs)
        self.after_handle()
        return ret

    return decorated


class NotUse:

    @staticmethod
    def set_location_box_property(obj: 'bpy.types.Object'):
        """设置定位Box属性
        如果
        """
        obj.hide_render = False

        obj.display_type = 'BOUNDS'
        obj.show_bounds = True
        obj.display_bounds_type = 'BOX'

        # 在预览时不显示
        obj.visible_camera = False
        obj.visible_diffuse = False
        obj.visible_glossy = False
        obj.visible_transmission = False
        obj.visible_volume_scatter = False
        obj.visible_shadow = False

    def load_scene_to_collection(self, blend_path: 'str', collection: 'bpy.types.Collection') -> 'bpy.types.Collection':
        """TODO 导入场景作为集合"""

    @property
    def is_have_location_empty(self) -> bool:
        """是否佣用定位Box的布尔值"""
        return False


class TranslationAndParent:
    """存放设置资产的变换和父级关系的类
    在导入匹配
    """

    @classmethod
    def get_collection_max_bound(cls, col: 'bpy.types.Collection'):
        """获取集合最大边界框"""
        objects = col.all_objects
        bound_box = [[0, 0] for _ in range(3)]  # (max,min)取三轴最大和最小轴

        def get_max_and_min(location):
            for axis, value in enumerate(location):
                if value < bound_box[axis][1]:  # 小
                    bound_box[axis][1] = value
                elif value > bound_box[axis][0]:  # 大
                    bound_box[axis][0] = value

        for obj in objects:
            for bb in obj.bound_box:
                lo = obj.matrix_world @ Vector((bb[:]))
                get_max_and_min(lo)
        return bound_box

    @classmethod
    def from_collection_get_matrix(cls, col: 'bpy.types.Collection') -> 'Matrix':
        """获取集合所在的矩阵,中心点放在中间
        """
        mat = Matrix()

        max_bound = cls.get_collection_max_bound(col)
        axis_max = [i[0] - i[1] for i in max_bound]  # 每个轴的尺寸

        max_size = max(axis_max)  # 最大的尺寸

        midpoint = [max_bound[index][0] - value /
                    2 for index, value in enumerate(axis_max)]  # 中点

        mat @= Matrix.Translation(Vector(midpoint)) @ Matrix.Scale(max_size / 2, 4)
        z = axis_max[2]
        if max_size != z:  # 如果最长的不是z轴,就做特殊处理,把物体的最低点降到z0
            mat = Matrix.Translation(Vector((0, 0, (max_size - z) / 2))) @ mat

        return mat

    @classmethod
    def collection_translation_to_matrix(cls, col: 'bpy.types.Collection', mat: 'Matrix') -> None:
        """TODO 集合变换到矩阵"""
        bound_matrix = cls.from_collection_get_matrix(col)
        for obj in col.all_objects:
            if not obj.parent:
                # 如果没有父级则确认更改矩阵
                obj.matrix_world = bound_matrix.inverted() @ obj.matrix_world  # 先还原至原点的位置

                if not Preferences.pref_().import_set_parent_form_tag:  # 如果不设置父级就作用上去,设置父级就不作用
                    obj.matrix_world = mat @ obj.matrix_world

    @classmethod
    def collection_translation_to_object(cls, col: 'bpy.types.Collection', matching_object: 'bpy.types.Object') -> None:
        """集合内的所有物体变换到目标物体内"""
        cls.collection_translation_to_matrix(col, matching_object.matrix_world)

    @classmethod
    def clear_collection_translation(cls, col: 'bpy.types.Collection') -> None:
        """将集合物体的变换信息归零,避免出现重复应用矩阵
        在fixed 物体时使用
        但是如果一个场景里面有多个物体的话也会出现其它问题
        """
        for obj in col.all_objects:
            obj.matrix_world @= obj.matrix_world.inverted()

    @classmethod
    def unlink_collection_children(cls, col: 'bpy.types.Collection', unlink_obj=False) -> None:
        """取消链接集合子集
        物体链接单独处理
        """
        for co in col.children:
            cls.clear_collection_translation(co)
            col.children.unlink(co)
        if unlink_obj:
            for obj in col.objects:
                col.objects.unlink(obj)
        col.update_tag()

    @classmethod
    def clear_preview_collection(cls) -> None:
        """清理预览集合
        将会在场景中新键并链接"""
        col = cls.preview_collection_()
        log.info(f'clear_preview_collection {col}', )
        cls.unlink_collection_children(col)

    @classmethod
    def link_to_collect(cls, data, collect: 'bpy.types.Collection') -> None:
        """链接数据集合里面
        """
        from collections.abc import Iterable

        if isinstance(data, Iterable):
            for d in data:
                cls.link_to_collect(d, collect)
        elif isinstance(data, bpy.types.Object):
            if data not in collect.objects[:]:
                collect.objects.link(data)
        elif isinstance(data, bpy.types.Collection) and (data not in collect.children[:]):
            collect.children.link(data)

    def set_collection_translation(self, col) -> None:
        """
        将预览集合里面的东西放到目标里面
        """
        tag_empty = self.location_box
        have_col = self._have_collection(self.asset_preview_collect_name)

        text = 'set_collection_translation' + str(tag_empty) + str(self.asset_path) + str(have_col)
        log.debug(text)
        if tag_empty and self.pref.import_to_location_box:  # 有空物体并且是要导入到定位框
            if self.is_direct_import and isinstance(self.import_asset_tmp_save, bpy.types.Collection):
                col = self.import_asset_tmp_save
            log.debug(f'import_to_location_box {col}')

            if not self.is_confirm_preview_import:
                self.collection_translation_to_object(col, tag_empty)
                self.set_object_parent(col, tag_empty)

    def set_object_parent(self, col: 'bpy.types.Collection', parent: 'bpy.types.Object') -> None:
        """设置父级"""
        pref = AssetUtils.pref_()
        for obj in col.all_objects:
            if (not obj.parent) and pref.import_set_parent_form_tag and self.is_import_object and (obj != parent):
                obj.parent = parent

    # Translation
    def import_to_cursor(self) -> None:
        """导入到游标
        """
        is_obj = self.asset_type.lower() == 'object'
        if self.is_import_twice_in_a_row:
            # 如果第二次导入就不再作用上去了,因为第一次经弄了
            return

        if self.pref.import_to_cursor and is_obj and self.import_asset_tmp_save:
            matrix = bpy.context.scene.cursor.matrix
            item = self.import_asset_tmp_save
            if isinstance(item, bpy.types.Collection):
                log.info("import_to_cursor")
                for obj in item.all_objects:
                    obj.matrix_world = matrix @ obj.matrix_world

    def set_translation(self) -> None:
        """设置变换
        """
        if self.is_import_object:
            self.import_to_cursor()
            self.set_collection_translation(self.get_collection)


class Remove:
    preview_collection_children: object
    is_preview_import = None

    def remove_scene_collection(self):
        """删除场景的集合"""
        col = self.get_collection
        if self.is_scene_collection:
            for i in col.children:
                self.del_collection(i, True, True)

    def remove_last_scene_libraries(self) -> None:
        """删除上一次资产库"""
        objects = self.get_collection.all_objects
        if objects:
            lib = objects[-1].library
            if lib:
                bpy.data.libraries.remove(lib)

    def remove_scene_libraries(self) -> None:
        """删除本次导入的库"""
        if self.pref.import_link:
            return
        self.remove_lib(self.asset_file)

    def remove_preview_collection(self) -> None:
        """删除预览集合
        preview_data
        如果连续两次导入都是一样的集合则把预览的集合给删喽
        然后将集合里面的内容链接到活动集合或是场景集合
        """
        if self.is_confirm_preview_import:
            # 连续导入两次一样的资产,直接把预览这个集合给删了
            preview = self.get_preview_collection
            if preview:
                self.preview_collection_children = preview.children[:]
                self.del_collection(preview)

    def remove_preview_libraries(self) -> None:
        """Remove Import Lib
        删除导入库

        预览/直接 导入

        关联/追加 导入

        如果是预览导入的话 一定要删库,如果是关联则删之前预览的库,如果是追加则直接删当前导入的

        如果是直接导入的话只删不是关联导入的
        """

        if self.is_import_twice_in_a_row and self.pref.import_link:
            # 如果是第二次导入并且是链接导入就不删掉了
            return

        if self.is_preview_import or (not self.pref.import_link):
            # 如果是关联导入只会删上一次导入的关联库
            name = split_path(self.last_asset_path)[
                1] if self.pref.import_link else self.asset_file

            self.remove_lib(name)

    # Remove Asset

    @classmethod
    def get_lib(cls, name: str) -> 'bpy.data.libraries':
        """获取库"""
        lib = bpy.data.libraries.get(name)
        return lib

    def remove_lib(self, lib_name: str) -> None:
        """删除库
        如果库存在的话
        """
        lib = self.get_lib(lib_name)
        if lib and (not lib.render_master.is_import_asset):  # 如果存在库并且不是已经导入了的库就删除
            text = '  remove lib' + str(lib.render_master.is_import_asset) + str(lib)
            log.info(text)
            bpy.data.libraries.remove(lib)

    def remove_preview_asset_recursive(self) -> None:
        """递归删除预览资产,将预览集合里面
        所有在此blender里面的数据都删掉(保留预览集合)
        将删除队列设置到计时器里面队列删除
        """

        if self.is_preview_import and (not self.is_import_twice_in_a_row):
            preview = self.get_preview_collection

            log.info(f'remove_preview_asset_recursive {preview}')

            for col in preview.children[:]:
                # 删除预览集合里面的所有子集合
                self.del_collection(col, True, True)

                if col and (col in preview.children[:]):
                    preview.children.unlink(col)

            self.queue_del_object(preview.objects[:])  # 删除预览集合里面所有物体，


class Property:
    scene_collect_name = 'RenderMaster-场景'  # RenderCollection,导入到当前场景的名称
    asset_preview_collect_name = 'RenderMaster-预览'  # 预览集合名称,固定值
    import_asset_tmp_save: list  # 导入的资产数据,导入的是个啥,存在这个里面
    preview_collection_children: None = None  # 记录预览时导入两次资产的数据

    asset_path: StringProperty(name='资产路径',
                               description='资产的路径,用于导入时确定路径')  # 绝对路径
    asset_type: StringProperty(name='资产类型', )  # 全大写
    last_asset_path: StringProperty(name='上一次导入路径',
                                    description='上一次预览导入的资产路径,只有在预览导入模式才会使用此属性',
                                    options={'SKIP_SAVE'},
                                    )

    use_last_data = True  # 使用上一次使用数量,暂时只有路径可设置

    # PROPERTY
    # BOOl -------------------------------

    @property
    def is_import_scene(self) -> bool:
        """是导入场景
        """
        return self.asset_type.upper() == 'SCENE'

    @property
    def is_import_object(self) -> bool:
        """是导入物体"""
        return self.asset_type.upper() == 'OBJECT'

    @property
    def is_have_preview_collection_scene(self) -> bool:
        """反回当前场景中是否有预览集合的布尔值"""
        name = self.asset_preview_collect_name
        return self._have_collection(name)

    @property
    def is_imported_link(self) -> bool:
        """反回是否确认已关联导入的布尔值
        就是已经完全导入而不是预览
        """
        preview_link = (
                self.is_confirm_preview_import and self.pref.import_link)  # 预览链接导入
        direct_import = (
                self.pref.is_direct_import and self.pref.import_link)  # 直接导入
        return preview_link or direct_import

    @property
    def is_scene_collection(self) -> bool:
        """反回集合是否为场景的布尔值"""
        return self.get_collection.name == self.scene_collect_name

    @property
    def is_import_twice_in_a_row(self) -> bool:
        """反回是否连续导入两次的布尔值
        """

        return self.last_asset_path == self.asset_path

    @property
    def is_confirm_preview_import(self) -> bool:
        """预览确认导入
        连续两次导入都是一个资产并且是预览导入模式
        """
        return self.is_import_twice_in_a_row and self.is_preview_import

    # GET -------------------------------
    @classmethod
    def preview_collection_(cls, ) -> 'bpy.types.Collection':
        """反回预览集合
        并将集合链接在场景内"""

        name = cls.asset_preview_collect_name
        return cls._get_collection(name)

    @classmethod
    def _link_preview_collection_to_scene(cls) -> 'bpy.types.Collection':
        """链接预览集合到场景
        并反回预览集合"""
        name = cls.asset_preview_collect_name
        if cls._have_collection(name):
            return bpy.data.collections[name]
        else:
            co = cls.preview_collection_()
            return co

    @property
    def get_preview_collection_data(self) -> 'bpy.context.collection':
        """反回预览集合的blender数据
        """
        name = self.asset_preview_collect_name
        return self._get_collection_data(name)

    @property
    def get_preview_collection(self) -> 'bpy.context.scene.collection':
        """反回预览使用的集合
        如果没有就当场新键一下
        如果确定导入了就需要删除
        """
        return self.preview_collection_()

    @property
    def get_scene_collection(self) -> 'bpy.context.scene.collection':
        """反回场景集合"""
        return bpy.context.scene.collection

    @property
    def get_active_collection(self) -> 'bpy.context.scene.collection':
        """反回活动集合
        用于导入资产到活动集合
        如果活动集合是预览的集合的话就直接导入到场景的集合里面
        """
        col = bpy.context.collection
        return self.get_scene_collection if self.check_collection_is_preview(col) else col

    @property
    def get_collection(self) -> 'bpy.context.scene.collection':
        """反回活动集合
        用于导入到场景用
        如果勾选了导入到活动集合则查找活动的集合
        否则就直接反回场景集合
        """
        pref = self.pref

        if self.is_import_scene:
            return self._get_collection(self.scene_collect_name)

        # Object
        if self.is_preview_import and (not self.is_import_twice_in_a_row):
            return self.get_preview_collection

        elif pref.import_to_active_collect:
            return self.get_active_collection
        return self.get_scene_collection

    @property
    def libraries(self) -> 'bpy.types.Library':
        """反回资产库
        """
        return bpy.data.libraries.get(self.asset_name)

    @property
    def asset_name(self) -> str:
        """反回资产的名称"""
        return splitext(self.asset_file)[0]

    @property
    def asset_file(self) -> str:
        """反回资产的文件名称"""
        return split_path(self.asset_path)[1]

    @property
    def asset_folder(self) -> str:
        """
        反回资产文件夹路径
        """
        return dirname(self.asset_path)

    @property
    def asset_category(self) -> dict:
        """反回资产分类的字典
        """
        diction = {}
        for key, value in self.asset_structure.items():
            if isinstance(value, dict):
                for k in value['category']:
                    diction[k] = key
        return diction

    @property
    def translation_collection(self):
        """TODO 反回需要变换的集合
        return 'bpy.types.Collection'
        """
        return None


class AssetUtils(Preferences,
                 TranslationAndParent,
                 Property,
                 Remove,
                 ):
    """资产工具,导入资产和导出资产时使用"""

    # func -------------------------------

    @classmethod
    def poll(cls, context) -> bool:
        """反回如果资产是文件夹则使用
        """
        return os.path.isdir(cls.pref_().asset_root_path)

    @staticmethod
    def walk(path: str):
        """反回路径
        """
        if not os.path.isdir(path):
            log.info(path + "\t不是一个文件夹")
            return
        walk = os.walk(path)
        return next(walk)

    @staticmethod
    def set_use_fake_user(objects, use_fake_user: bool) -> None:
        """
        设置是否使用伪用户
        输入一个可迭代列表
        TODO 标记物体下的其它子项如材质图片等
        """
        for obj in objects:
            if obj.data:
                obj.use_fake_user = use_fake_user

    @classmethod
    def del_collection(cls, col: 'bpy.context.collection', del_child=False, del_obj=False) -> None:
        """队列删除集合"""

        if col.library and col.library.render_master.is_import_asset:
            return

        if del_obj:
            # 队列删除物体
            cls.queue_del_object(col.objects[:])
        if del_child:
            # 循环删除子级
            for co in col.children[:]:
                cls.del_collection(co, del_child, del_obj)
        bpy.data.collections.remove(col)  # 最后删除集合

    @classmethod
    def queue_del_object(cls, obj: 'bpy.types.Object') -> None:
        """循环删除物体
        : 'bpy.context.object' | list('bpy.context.object')
        """
        from collections.abc import Iterable
        from ..utils.update import Timers

        asset_remove_list = Timers.asset_preview_remove_list
        if isinstance(obj, Iterable):
            asset_remove_list.extend(obj)  # 将需要删除的物体添加到待删除列表
        else:
            asset_remove_list.append(obj)

    @classmethod
    def check_collection_is_preview(cls, col: 'bpy.types.Collection') -> bool:
        """反回输入集合是否为预览的布尔值"""
        return col.name == cls.asset_preview_collect_name

    def save_import_asset(self, value) -> None:
        """设置导入的资产
        将导入的资产存下来"""
        self.import_asset_tmp_save = value

    def make_local_collect_object(self) -> None:
        """取消链接集合和物体
        仅保留物体数据
        避免变换无效
        """

        def unlink_obj(obj: 'bpy.types.Object'):
            obj.make_local()
            for ob in obj.children[:]:
                unlink_obj(ob)

        def unlink_col(col: 'bpy.types.Collection'):
            col.make_local()
            for c in col.children[:]:
                unlink_col(c)

            for obj in col.objects[:]:
                unlink_obj(obj)

        asset = self.import_asset_tmp_save
        if asset:
            from collections.abc import Iterable
            if isinstance(asset, bpy.types.Scene):
                # 是场景
                asset.make_local()
                unlink_col(asset.collection)
            elif isinstance(asset, Iterable):
                for co in asset:
                    unlink_col(co)
            elif isinstance(asset, bpy.types.Collection):
                unlink_col(asset)
            else:
                log.info(f'这是啥资产啊, 我不知道啊 {asset}')

    def import_world(self):
        """导入世界环境
        只会导入第一个,其它的不管
        """
        with self.libraries_load() as (data_from, data_to):
            if data_from.worlds:
                worlds = data_to.worlds = data_from.worlds
            else:
                worlds = None

        if worlds:
            world = worlds[0]
            bpy.context.scene.world = world

    '''操作符属性'''

    # Pre func

    @staticmethod
    def _libraries_load(blend_path: str, link: bool) -> 'bpy.types.Library':
        """加载库"""
        return bpy.data.libraries.load(blend_path, link=link)

    def libraries_load(self) -> 'bpy.types.Library':
        """反回加载库"""
        link = self.pref.import_link
        return self._libraries_load(self.asset_path, link)

    @classmethod
    def _have_collection(cls, name) -> bool:
        """反回场景内是否有输入集合名称"""
        children = bpy.context.scene.collection.children
        return bool(children.get(name))

    @classmethod
    def _get_collection_data(cls, name) -> 'bpy.types.Collection':
        """获取集合数据
        如果没有则当场新建一个
        """
        collections = bpy.data.collections
        collect = collections.get(name, collections.new(name))
        return collect

    @classmethod
    def _get_collection(cls, name) -> 'bpy.types.Collection':
        """获取集合"""
        child = bpy.context.scene.collection.children
        if not cls._have_collection(name):
            child.link(cls._get_collection_data(name))
        return child.get(name)

    def from_file_load_valid_collection(self, collection_name: str) -> 'bpy.types.Collection':
        """从文件加载有效集合,输入集合名称"""
        with self.libraries_load() as (data_from, data_to):
            '''查找是否有匹配的集合'''
            matching_collect = [
                i for i in data_from.collections if i == collection_name]

            if matching_collect:
                data_to.collections = matching_collect
            else:
                log.info(f'未找到有效集合:{collection_name}')
                return
        return matching_collect[0]

    def load_objects_to_collection(self, blend_path: 'str',
                                   collection: 'bpy.types.Collection') -> 'bpy.types.Collection':
        """加载物体到集合"""
        with self.libraries_load() as (data_from, data_to):
            objects = data_to.objects = data_from.objects
        for obj in objects:
            collection.objects.link(obj)
        return collection

    def from_file_load_collection(self) -> 'bpy.types.Collection':
        """获取有效集合"
        从输入路径里面的.blend文件 获取 self.
        如果找到了就直接反回
        如果没找到就新建一个集合,将里面的所有物体导入到这个集合里面
        """
        col = self.from_file_load_valid_collection(self.asset_name)
        if col:
            # 找到了匹配的集合
            return col
        else:
            # 没找到,导入场景内的所有物体,然后再导入到名称的集合
            col_data = self._get_collection_data(self.asset_name)
            self.unlink_collection_children(col_data)
            self.load_objects_to_collection(self.asset_path, col_data)
            return col_data

    def mark_library_imported(self) -> None:
        """标记库已导入的属性
        用于避免把已经导入过的关联库再给删喽
        prop:bpy.data.library.render_master.is_import_asset
        """
        lib = self.get_lib(self.asset_file)

        if lib:
            lib.render_master.is_import_asset |= self.is_imported_link

    def preview_handle(self) -> None:
        """预览处理
        如果类型没有在排除列表里

        判断一下是不是连续导入两次资产是一样的
        如果是则删除预览集合,按直接导入再导一下

        不是的话则删除集合里面的内容,再导一次
        """
        is_preview_asset = self.asset_type.upper() not in ('SCENE',)
        if is_preview_asset and self.is_preview_import:
            '''资产导入预览,排除场景
            '''
            col_prop = self.get_preview_collection.render_master
            # 记录并设置一下之前导入的资产路径,用于判断两次导入是否一致,如果不一致需要将预览集合里面的东西清掉
            self.last_asset_path = col_prop.last_import_asset_path
            col_prop.last_import_asset_path = self.asset_path

            if not self.is_have_preview_collection_scene:
                # 如果没有预览集合则新建一个
                self.get_preview_collection
            self.remove_preview_asset_recursive()  # 删除之前预览导入的东西

    @staticmethod
    def de_select() -> None:
        """取消选择物体"""
        if bpy.context.mode != 'OBJECT':
            bpy.ops.object.mode_set(mode='OBJECT')
        bpy.ops.object.select_all(action='DESELECT')

    def before_handle(self) -> None:
        # 处理选中项
        log.info(f'start import {self.asset_type}')
        if self.is_import_object:
            # 物体导入处理,取消选择，删除预览集合里面的内容,记录上一次的资产
            # AssetUtils.de_select()
            self.preview_handle()
            self.remove_preview_collection()
        elif self.is_import_scene:
            # 场景删除处理,将集合清理一下就行
            self.remove_last_scene_libraries()
            self.remove_scene_collection()

    def after_handle(self) -> None:
        """之后"""

        if self.is_import_object:
            self.mark_library_imported()
            self.remove_preview_libraries()
        elif self.is_import_scene:
            self.remove_scene_libraries()
            self.import_world()
        self.set_translation()  # 只有导入资产的时候设置位置
        self.make_local_collect_object()
        log.info(f'fished import\t {self.asset_type} {self.asset_path}')

    @import_handle
    def import_asset(self, context: 'bpy.context') -> None:
        """
        pref.import_mode
        pref.import_link
        pref.import_to_cursor
        pref.import_active_collect
        """

        if self.is_asset(self.asset_path, self.asset_type):
            func = getattr(self, f'import_{self.asset_type.lower()}')
            return func(context)

    # Import Func

    def link_preview_data(self) -> None:
        """把预览的集合删了
        将里面的内容链接到活动集合或是场景集合
        """
        cols = self.preview_collection_children
        self.save_import_asset(cols[0])
        for col in cols:
            if col in self.get_collection.children[:]:
                # 如果已经导入了就copy一份
                col = col.copy()
            self.get_collection.children.link(col)

    def import_object(self, context) -> 'bpy.types.Collection':
        """导入产品
        导入到活动集合
        导入到场景里面的定位盒
        导入到游标位置
        """

        if self.is_confirm_preview_import:
            # 预览导入并且连续导了两次,不用再导一下资产了
            self.link_preview_data()
            return

        matching_collect = self.from_file_load_collection()  # 获取匹配集合

        # return
        if matching_collect and (matching_collect in self.get_collection.children[:]):
            '''如果集合已经在这个里面了
            比如关联导入再关联导入一个,就会出现这样的情况
            这时候需要复制一份
            并且把这个直接给弄成集合,而不是列表
            '''
            matching_collect = matching_collect.copy(
            )

        self.get_collection.children.link(matching_collect)
        self.set_use_fake_user(matching_collect.objects,
                               self.pref.import_use_fake_user)
        self.save_import_asset(matching_collect)

        return matching_collect

    def import_scene(self, context) -> None:
        """导入场景
        A 将场景文件的匹配集合导入到当前场景的集合
        B 将场景文件的整个场景导入，同时会保留 之前场景的渲染信息和其它的所有,如果没有场景则会使用A
        删除上次导入场景
        """
        whole_scene = self.pref.import_whole_scene
        if whole_scene:
            self.import_scene_whole(context)
        else:
            self.import_scene_as_collection(self.get_collection)

    def import_scene_whole(self, context) -> None:
        """整个场景导入
        而不是导入到集合
        """
        link = self.pref.import_link
        with bpy.data.libraries.load(self.asset_path, link=link) as (from_data, to_data):
            matching_scene = [
                scene for scene in from_data.scenes if scene == self.asset_name]
            if matching_scene:
                # 匹配了
                to_data.scenes = matching_scene
            elif from_data.scenes:
                # 没匹配但有内容,留第一个场景用作导入
                matching_scene = to_data.scenes = from_data.scenes[:1]
            else:
                # 没区配也没内容,改为导入到集合
                self.import_scene_as_collection(context)
                log.info(f'未找到有效场景:{self.asset_name} 导入为物体')
                return

        scene = matching_scene[0]
        scene.name = self.asset_name  # 改名
        scene.render_master.is_import_asset = True
        bpy.context.window.scene = scene  # 设置活动场景
        self.save_import_asset(scene)

    def import_scene_as_collection(self, collection: 'bpy.types.Collection') -> None:
        """将场景作为集合导入

        Args:
            collection (bpy.types.Collection): 输入需要链接到的集合,导入到活动场景
        """

        matching_collect = self.from_file_load_collection()  # 获取匹配集合
        collection.children.link(matching_collect)
        self.save_import_asset(matching_collect)
